<template>
  <div class="service-role row no-wrap justify-between">
    <q-list class="bg-white-6 shadow-1  overflow-auto-y rounded-borders q-mr-md" separator>
      <q-item class="flex-center text-subtitle1 q-pt-md text-bold">
        {{ $t('ServiceList') }}
      </q-item>
      <MEmpty v-if="!serviceList.length"></MEmpty>
      <q-item v-for="service in serviceList" :key="service.id" v-ripple :active="service.id === currentService.id"
              active-class="service-active-cls" clickable @click="serviceClick(service)">
        <q-item-section avatar>
          <q-icon name="admin_panel_settings" size="1.25rem" />
        </q-item-section>
        <q-item-section>
          <qx-tooltip>{{ service[toI18nName('serviceNameZhCn')] }}</qx-tooltip>
        </q-item-section>
      </q-item>
    </q-list>
    <qx-tree v-model="selected" :filter-method="filterMethod" :options="menuList" :props="props" :showWay="menuBtn"
             classes="bg-white col" multiple strategy="strict" @change="treeChange">
      <template v-slot:header="{ prop }">
        <div class="row items-center">
          <q-icon :name="menuIcon(prop.node)" class="q-mr-sm" size="1.25rem" />
          <div class="text-weight-bold">{{ prop.node.code }} -- {{ prop.node[toI18nName('menuNameZhCn')] }}</div>
        </div>
      </template>
    </qx-tree>
  </div>
  <div v-if="menuBtn" class="qx-page-footer row justify-center q-pt-sm q-mb-sm q-gutter-x-md rounded-borders">
    <q-btn :loading="loading" color="primary" icon="published_with_changes" unelevated v-bind="menuBind"
           @click="submitRole">
      {{ $t('Confirm') }}
    </q-btn>
    <q-btn :loading="loading" icon="cancel_schedule_send" outline text-color="primary" v-bind="menuBind"
           @click="closePage">
      {{ $t('Close') }}
    </q-btn>
  </div>
  <q-inner-loading :showing="loading">
    <q-spinner-ios color="primary" size="3rem" />
  </q-inner-loading>
</template>

<script setup>
import { toI18nName } from 'boot/i18n'
import { postAPI } from 'src/api'
import { userStores } from 'stores/user-stores'
import { computed, ref, watch } from 'vue'

const prop = defineProps({
  rowInfo: Object, menusList: Array, menuBtn: Boolean, modelValue: Boolean
})

const userStore = userStores()
const menuList = ref([])
const selected = ref([])
const loading = ref(false)
const serviceList = ref([])
const selectedAllMenus = ref({})
const menuBind = { 'no-wrap': true, padding: '.4rem 1rem' }
const currentService = ref(userStore.breadcrumbs || {})
const modalVisible = defineModel('modelValue', { type: Boolean, default: false })
const maxHeight = computed(() => prop.menuBtn ? 'calc(100% - 2.875rem)' : 'calc(100% - 0.375rem)')

watch(modalVisible, val => {
  if (!val) return
  selected.value = prop.menusList || []
  selectedAllMenus.value = [...selected.value]
}, { immediate: true })

const props = { label: toI18nName('menuNameZhCn'), children: 'childs' }

const menuIcon = computed(() => {
  return menu => {
    if (menu.menuIcon) return menu.menuIcon
    if (menu.menuType === 'F') return 'storage'
    if (menu.menuType === 'M') return 'insert_chart'
    return 'smart_button'
  }
})

const getServiceMenus = () => {
  if (!loading.value) loading.value = true
  if (!currentService.value || !currentService.value.id) {
    loading.value = false
    return
  }
  const params = {
    orderByItems: [{ property: 'sortId', orderType: 'ASC' }],
    andDynamicQueryItems: [{ property: 'serviceId', value: currentService.value.id, criterion: 'andEqualTo' }]
  }
  menuList.value = []
  postAPI('/auth/api/authMenu/listTree', params, data => {
    menuList.value = data
    loading.value = false
  }, () => {
    loading.value = false
  })
}

const getServiceList = () => {
  loading.value = true
  postAPI('/auth/api/authService/list', { pageSize: '-1' }, data => {
    serviceList.value = data.rows
    getServiceMenus()
  }, () => {
    loading.value = false
  })
}
getServiceList()

const serviceClick = service => {
  if (service.id === currentService.value.id) return
  currentService.value = service
  getServiceMenus()
}

const filterMethod = (node, filter) => {
  const query = (filter || '').toUpperCase()
  if ((node.code || '').toUpperCase().includes(query)) return true
  return (node[toI18nName('menuNameZhCn')] || '').toUpperCase().includes(query)
}

const treeChange = (target, _, AllNodesKey) => {
  const nonSel = AllNodesKey.filter(el => !target.includes(el))
  selectedAllMenus.value =
    Array.from(new Set([...selectedAllMenus.value, ...target])).filter(el => !nonSel.includes(el))
}

const done = flag => {
  loading.value = false
  modalVisible.value = !!flag
}
const closePage = () => modalVisible.value = false
const submitRole = () => {
  const params = { roleId: prop.rowInfo.id, menuIds: selectedAllMenus.value }
  loading.value = true
  postAPI('/auth/api/authRole/resetMenus', params, () => done(), () => done(false))
}
</script>
<style lang="scss" scoped>
.service-role {
  max-height: v-bind(maxHeight);
}
</style>